From 2d99d6a2090346f2ca71ead46207ec0f538059df Mon Sep 17 00:00:00 2001 From: "maf46@burn.cl.cam.ac.uk" Date: Fri, 25 Feb 2005 16:07:27 +0000 Subject: [PATCH] bitkeeper revision 1.1236.1.25 (421f4d3f1OCTsnYVCTM2mhwvFDIGvA) alloc_monitor_pagetable/update_pagetable cleanup. update_pagetable() is now the only code that (ever) sets arch.monitor_table. update_pagetable() is also now smart enough to deal with VMX guests while their paging is still disabled. Signed-off-by: michael.fetterman@cl.cam.ac.uk --- xen/arch/x86/domain.c | 13 ++++--------- xen/include/asm-x86/shadow.h | 25 ++++++++++++++++++++++++- xen/include/xen/domain.h | 2 ++ 3 files changed, 30 insertions(+), 10 deletions(-) diff --git a/xen/arch/x86/domain.c b/xen/arch/x86/domain.c index d3f2076cbe..f2b46e8c07 100644 --- a/xen/arch/x86/domain.c +++ b/xen/arch/x86/domain.c @@ -295,7 +295,7 @@ void arch_vmx_do_launch(struct exec_domain *ed) reset_stack_and_jump(vmx_asm_do_launch); } -static void alloc_monitor_pagetable(struct exec_domain *ed) +unsigned long alloc_monitor_pagetable(struct exec_domain *ed) { unsigned long mmfn; l2_pgentry_t *mpl2e; @@ -319,12 +319,13 @@ static void alloc_monitor_pagetable(struct exec_domain *ed) mk_l2_pgentry((__pa(d->arch.mm_perdomain_pt) & PAGE_MASK) | __PAGE_HYPERVISOR); - ed->arch.monitor_table = mk_pagetable(mmfn << PAGE_SHIFT); ed->arch.monitor_vtable = mpl2e; // map the phys_to_machine map into the Read-Only MPT space for this domain mpl2e[l2_table_offset(RO_MPT_VIRT_START)] = mk_l2_pgentry(pagetable_val(ed->arch.phys_table) | __PAGE_HYPERVISOR); + + return mmfn; } /* @@ -408,13 +409,7 @@ static int vmx_final_setup_guest(struct exec_domain *ed, shadow_mode_enable(ed->domain, SHM_enable|SHM_translate|SHM_external); } - /* We don't call update_pagetables() as we actively want fields such as - * the linear_pg_table to be inaccessible so that we bail out early of - * shadow_fault() in case the vmx guest tries illegal accesses with - * paging turned off. - */ - //update_pagetables(ed); /* this assigns shadow_pagetable */ - alloc_monitor_pagetable(ed); /* this assigns monitor_pagetable */ + update_pagetables(ed); return 0; diff --git a/xen/include/asm-x86/shadow.h b/xen/include/asm-x86/shadow.h index c02079fa89..670394ce60 100644 --- a/xen/include/asm-x86/shadow.h +++ b/xen/include/asm-x86/shadow.h @@ -781,13 +781,27 @@ static inline void __update_pagetables(struct exec_domain *ed) static inline void update_pagetables(struct exec_domain *ed) { struct domain *d = ed->domain; + int paging_enabled = +#ifdef CONFIG_VMX + !VMX_DOMAIN(ed) || + test_bit(VMX_CPU_STATE_PG_ENABLED, &ed->arch.arch_vmx.cpu_state); +#else + 1; +#endif - if ( unlikely(shadow_mode_enabled(d)) ) + /* + * We don't call __update_pagetables() when vmx guest paging is + * disabled as we want the linear_pg_table to be inaccessible so that + * we bail out early of shadow_fault() if the vmx guest tries illegal + * accesses while it thinks paging is turned off. + */ + if ( unlikely(shadow_mode_enabled(d)) && paging_enabled ) { shadow_lock(d); __update_pagetables(ed); shadow_unlock(d); } + if ( !shadow_mode_external(d) ) { #ifdef __x86_64__ @@ -800,6 +814,15 @@ static inline void update_pagetables(struct exec_domain *ed) else ed->arch.monitor_table = ed->arch.guest_table; } + else + { + // External page tables... + // Allocate a monitor page table if we don't already have one. + // + if ( unlikely(!pagetable_val(ed->arch.monitor_table)) ) + ed->arch.monitor_table = + mk_pagetable(alloc_monitor_pagetable(ed) << PAGE_SHIFT); + } } #if SHADOW_DEBUG diff --git a/xen/include/xen/domain.h b/xen/include/xen/domain.h index 15db59d73d..8db16e2512 100644 --- a/xen/include/xen/domain.h +++ b/xen/include/xen/domain.h @@ -27,4 +27,6 @@ extern void domain_relinquish_memory(struct domain *d); extern void dump_pageframe_info(struct domain *d); +extern unsigned long alloc_monitor_pagetable(struct exec_domain *ed); + #endif /* __XEN_DOMAIN_H__ */ -- 2.30.2